using System;

namespace WillStott.MxAppToolbox
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	public class UniException : ApplicationException
	{
		public enum Category { System, Resource, Data, User, Program }
		public enum Reset { AbortOp, Reinit, TermApp }

		private string   m_MsgId;
		private Reset    m_Reset;
		private Category m_Category;
		private string   m_Fmt;
		private object[] m_Args;

		public UniException( string aMsgId, Reset aResetAction, Category aCategory, string aFmt, params object[] aArgs) : base(String.Format(aFmt, aArgs))
		{
			Init(aMsgId, aResetAction, aCategory, aFmt, aArgs);

		}
		public UniException( string aMsgId, Reset aResetAction, Category aCategory, Exception Inner, string aFmt, params object[] aArgs) : base(String.Format(aFmt, aArgs) ,Inner)
		{
			Init(aMsgId, aResetAction, aCategory, aFmt, aArgs);
		}

		private void Init(string aMsgId, Reset aMsgReset, Category aMsgCategory, string aFmt, object[] aArgs)
		{
			m_MsgId = aMsgId;
			m_Reset = aMsgReset;
			m_Category = aMsgCategory;
			m_Fmt = aFmt;
			m_Args = aArgs;
		}

		public override string ToString()
		{
			string rc = MsgId + ": ";
			
			rc += this.Message + Environment.NewLine;

			int Nesting = 0;
			for ( Exception e = this; e != null; e = e.InnerException)
			{
				if ( Nesting == 0 )
					rc += Environment.NewLine + "Outer Exception:" + Environment.NewLine;
				else
					rc += string.Format("Inner Exception-{0}:{1}", Nesting, Environment.NewLine);
				rc += "................................................." + Environment.NewLine;
				if ( (e.GetType() != null) && (e.GetType().Name != null ))
					rc += string.Format("Exception Type: {0}{1}", e.GetType().Name, Environment.NewLine);
				if ( (Nesting > 0 ) && (e.Message != null))	
					rc += string.Format("Msg: {0}{1}", e.Message.ToString(), Environment.NewLine);
				if ( e.Source != null ) 
					rc += string.Format("Source: {0}{1}",  e.Source.ToString(), Environment.NewLine);
				if ( e.TargetSite != null )
					rc += string.Format("Target: {0}{1}", e.TargetSite.ToString(), Environment.NewLine);
				if ( e.StackTrace != null )
					rc += string.Format("Stack: {0}{1}", e.StackTrace.ToString(), Environment.NewLine);
				rc += "................................................." + Environment.NewLine;
				Nesting++;
			}
			return rc;
		}

		public  string MsgId
		{
			get { return m_MsgId; }
		}
		public Reset ResetAction
		{
			get { return m_Reset; }
		}

		public Category Class
		{
			get { return m_Category; }
		}
		public string Fmt
		{
			get { return m_Fmt; }
		}
		public object[] Args
		{
			get { return m_Args; }
		}

	}
}
